
package com.android.finaltracer.model;

import java.util.ArrayList;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.AbstractCursor;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.provider.BaseColumns;
import android.text.TextUtils;
import android.util.Log;

import com.android.finaltracer.util.FTKey;

public class FTDataProvider extends ContentProvider {

    private static final String TAG = "FT_DEBUG";
    private static final UriMatcher sUriMatcher;

    public static final String AUTHORITY = "com.android.ft.provider.data";

    private static final String DATABASE_NAME = "ftsetting.db";
    private static final int DATABASE_VERSION = 1;
    private static final String RELATION_TABLE_NAME = "relationnumber";

    private static final int SETTING_PATH = 0;
    private static final int SETTING_IMSI = 1;
    private static final int SETTING_PHONES = 2;
    private static final int SETTING_PHONE_ID = 3;
    private static final int SETTING_IMEI = 4;

    private static final int RELATION_PATH = 5;
    private static final int RELATION_PATH_ID = 6;

    static {
        sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        sUriMatcher.addURI(FTKey.FT_DATA_PROVIDER_AUTHORITY,
                FTKey.SETTING_PATH, SETTING_PATH);
        sUriMatcher.addURI(FTKey.FT_DATA_PROVIDER_AUTHORITY,
                FTKey.SETTING_PATH_IMSI, SETTING_IMSI);
        sUriMatcher.addURI(FTKey.FT_DATA_PROVIDER_AUTHORITY,
                FTKey.SETTING_PATH_PHONE, SETTING_PHONES);
        sUriMatcher.addURI(FTKey.FT_DATA_PROVIDER_AUTHORITY,
                FTKey.SETTING_PATH_PHONE_ID, SETTING_PHONE_ID);
        sUriMatcher.addURI(FTKey.FT_DATA_PROVIDER_AUTHORITY,
                FTKey.SETTING_PATH_IMEI, SETTING_IMEI);
        sUriMatcher.addURI(FTKey.FT_DATA_PROVIDER_AUTHORITY,
                FTKey.RELATION_PATH, RELATION_PATH);
        sUriMatcher.addURI(FTKey.FT_DATA_PROVIDER_AUTHORITY,
                FTKey.RELATION_PATH_ID, RELATION_PATH_ID);
    }

    private static class DatabaseHelper extends SQLiteOpenHelper {

        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL("CREATE TABLE " + RELATION_TABLE_NAME + " ("
                    + RelationColumns._ID + " INTEGER PRIMARY KEY,"
                    + RelationColumns.NAME + " TEXT,"
                    + RelationColumns.NICKNAME + " TEXT,"
                    + RelationColumns.NUMBER + " TEXT NOT NULL,"
                    + RelationColumns.IMEI + " TEXT,"
                    + RelationColumns.RELATIONSHIP + " INTEGER DEFAULT(1),"
                    + RelationColumns.WEIGHT_TYPE + " INTEGER DEFAULT(1),"
                    + RelationColumns.GPS_TYPE + " INTEGER DEFAULT(1),"
                    + RelationColumns.GPS_ON + " INTEGER DEFAULT(1),"
                    + RelationColumns.GPS_LAT + " INTEGER DEFAULT(0),"
                    + RelationColumns.GPS_LNG + " INTEGER DEFAULT(0),"
                    + RelationColumns.MODIFIED_DATE + " INTEGER" + ");");
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                    + newVersion + ", which will destroy all old data");
            db.execSQL("DROP TABLE IF EXISTS notes");
            onCreate(db);
        }
    }

    private Setting mSettingData;
    private DatabaseHelper mOpenHelper;

    @Override
    public boolean onCreate() {
        // TODO Auto-generated method stub
        mSettingData = SettingCreator.settingInit(getContext());
        mOpenHelper = new DatabaseHelper(getContext());
        return true;
    }

    @Override
    public int delete(Uri uri, String where, String[] whereArgs) {
        // TODO Auto-generated method stub
        int result = -1;
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        try {
            switch (sUriMatcher.match(uri)) {
                case SETTING_IMSI:
                    mSettingData.setOldImsi("");
                    result = 0;
                    break;
                case SETTING_PHONES:
                    for (int i = 1; i < 6; i++) {
                        mSettingData.setAssociatedPhoneNum("", i);
                    }
                    result = 0;
                    break;
                case SETTING_PHONE_ID:
                    String phoneId = uri.getPathSegments().get(2);
                    int count = Integer.valueOf(phoneId).intValue();
                    mSettingData.setAssociatedPhoneNum("", count);
                    result = 0;
                    break;
                case SETTING_IMEI:
                    mSettingData.setOldImei("");
                    result = 0;
                    break;
                case RELATION_PATH:
                    result = db.delete(RELATION_TABLE_NAME, where, whereArgs);
                    getContext().getContentResolver().notifyChange(uri, null);
                    break;
                case RELATION_PATH_ID:
                    String relationID = uri.getPathSegments().get(1);
                    result = db.delete(RELATION_TABLE_NAME, RelationColumns._ID
                            + "="
                            + relationID
                            + (!TextUtils.isEmpty(where) ? " AND (" + where + ')'
                                    : ""), whereArgs);
                    getContext().getContentResolver().notifyChange(uri, null);
                    break;
            }
        } catch (Exception e) {
            result = -1;
        }
        return result;
    }

    @Override
    public String getType(Uri uri) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        // TODO Auto-generated method stub
        Uri result = null;
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        try {
            switch (sUriMatcher.match(uri)) {
                case SETTING_IMSI:
                    if (values.containsKey(FTKey.SETTING_COLUMN_IMSI)) {
                        mSettingData.setOldImsi(values
                                .getAsString(FTKey.SETTING_COLUMN_IMSI));
                    }
                    result = uri;
                    break;
                case SETTING_PHONES:
                    for (int i = 1; i < 6; i++) {
                        String tmp = mSettingData.getAssociatedPhoneNum(i);
                        if (tmp != null && tmp.length() > 0) {
                            continue;
                        }
                        if (values.containsKey(FTKey.SETTING_COLUMN_PHONES)) {
                            mSettingData
                                    .setAssociatedPhoneNum(
                                            values.getAsString(FTKey.SETTING_COLUMN_PHONES),
                                            i);
                            result = uri;
                            break;
                        }
                    }
                    break;
                case SETTING_PHONE_ID:
                    String phoneId = uri.getPathSegments().get(2);
                    int count = Integer.valueOf(phoneId).intValue();
                    if (values.containsKey(FTKey.SETTING_COLUMN_PHONES + phoneId)) {
                        mSettingData.setAssociatedPhoneNum(
                                values.getAsString(FTKey.SETTING_COLUMN_PHONES
                                        + phoneId), count);
                    }
                    break;
                case SETTING_IMEI:
                    if (values.containsKey(FTKey.SETTING_COLUMN_IMEI)) {
                        mSettingData.setOldImei(values
                                .getAsString(FTKey.SETTING_COLUMN_IMEI));
                    }
                    result = uri;
                    break;
                case RELATION_PATH:
                    Log.d("xiaojf", "on RELATION_PATH");
                    ContentValues tmpValues;
                    tmpValues = new ContentValues(values);
                    Long now = Long.valueOf(System.currentTimeMillis());
                    if (tmpValues.containsKey(RelationColumns.MODIFIED_DATE) == false) {
                        tmpValues.put(RelationColumns.MODIFIED_DATE, now);
                    }
                    long rowId = db.insert(RELATION_TABLE_NAME,
                            RelationColumns.NUMBER, tmpValues);
                    if (rowId > 0) {
                        result = ContentUris.withAppendedId(
                                RelationColumns.CONTENT_URI, rowId);
                        getContext().getContentResolver()
                                .notifyChange(result, null);
                    }
                    break;
            }

        } catch (Exception e) {
            result = null;
        }
        if (result != null) {
            Log.d("xiaojf", "on insert result ==" + result.toString());
        } else {
            Log.d("xiaojf", "on insert result == null");
        }
        return result;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        // TODO Auto-generated method stub
        Cursor result = null;
        MySettingCursor mySettingCursor = null;
        String orderBy;
        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
        qb.setTables(RELATION_TABLE_NAME);
        try {
            mySettingCursor = new MySettingCursor(new String[] {
                    FTKey.SETTING_COLUMN_IMSI, FTKey.SETTING_COLUMN_IMEI,
                    FTKey.SETTING_COLUMN_PHONE1, FTKey.SETTING_COLUMN_PHONE2,
                    FTKey.SETTING_COLUMN_PHONE3, FTKey.SETTING_COLUMN_PHONE4,
                    FTKey.SETTING_COLUMN_PHONE5
            });

            switch (sUriMatcher.match(uri)) {
                case SETTING_PATH:
                    mySettingCursor.addRow(new String[] {
                            mSettingData.getOldImsi(), mSettingData.getOldImei(),
                            mSettingData.getAssociatedPhoneNum(1),
                            mSettingData.getAssociatedPhoneNum(2),
                            mSettingData.getAssociatedPhoneNum(3),
                            mSettingData.getAssociatedPhoneNum(4),
                            mSettingData.getAssociatedPhoneNum(5)
                    });
                    result = mySettingCursor;
                    break;
                case SETTING_IMSI:
                    String tmpImsi = mSettingData.getOldImsi();
                    mySettingCursor.addRow(new String[] {
                            tmpImsi, null, null,
                            null, null, null, null
                    });
                    result = mySettingCursor;
                    break;
                case SETTING_PHONES:
                case SETTING_PHONE_ID:
                    mySettingCursor.addRow(new String[] {
                            null, null,
                            mSettingData.getAssociatedPhoneNum(1),
                            mSettingData.getAssociatedPhoneNum(2),
                            mSettingData.getAssociatedPhoneNum(3),
                            mSettingData.getAssociatedPhoneNum(4),
                            mSettingData.getAssociatedPhoneNum(5)
                    });
                    result = mySettingCursor;
                    break;
                case SETTING_IMEI:
                    mySettingCursor
                            .addRow(new String[] {
                                    null, mSettingData.getOldImei(),
                                    null, null, null, null, null
                            });
                    result = mySettingCursor;
                    break;
                case RELATION_PATH:
                    if (TextUtils.isEmpty(sortOrder)) {
                        orderBy = RelationColumns.DEFAULT_SORT_ORDER;
                    } else {
                        orderBy = sortOrder;
                    }
                    result = qb.query(db, projection, selection, selectionArgs,
                            null, null, orderBy);
                    result.setNotificationUri(getContext().getContentResolver(),
                            uri);
                    break;
                case RELATION_PATH_ID:
                    qb.appendWhere(RelationColumns._ID + "="
                            + uri.getPathSegments().get(1));
                    if (TextUtils.isEmpty(sortOrder)) {
                        orderBy = RelationColumns.DEFAULT_SORT_ORDER;
                    } else {
                        orderBy = sortOrder;
                    }
                    result = qb.query(db, projection, selection, selectionArgs,
                            null, null, orderBy);
                    result.setNotificationUri(getContext().getContentResolver(),
                            uri);
                    break;
            }
        } catch (Exception e) {
            result = null;
        }
        return result;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        // TODO Auto-generated method stub
        int result = -1;
        ContentValues tmpValues;
        Long now;
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        try {
            switch (sUriMatcher.match(uri)) {
                case SETTING_IMSI:
                    if (values.containsKey(FTKey.SETTING_COLUMN_IMSI)) {
                        mSettingData.setOldImsi(values
                                .getAsString(FTKey.SETTING_COLUMN_IMSI));
                    }
                    result = 0;
                    break;
                case SETTING_PHONE_ID:
                    String phoneId = uri.getPathSegments().get(2);
                    int count = Integer.valueOf(phoneId).intValue();
                    if (values.containsKey(FTKey.SETTING_COLUMN_PHONES + phoneId)) {
                        mSettingData.setAssociatedPhoneNum(
                                values.getAsString(FTKey.SETTING_COLUMN_PHONES
                                        + phoneId), count);
                    }
                    break;
                case SETTING_IMEI:
                    if (values.containsKey(FTKey.SETTING_COLUMN_IMEI)) {
                        mSettingData.setOldImei(values
                                .getAsString(FTKey.SETTING_COLUMN_IMEI));
                    }
                    result = 0;
                    break;
                case RELATION_PATH:
                    tmpValues = new ContentValues(values);
                    now = Long.valueOf(System.currentTimeMillis());
                    if (tmpValues.containsKey(RelationColumns.MODIFIED_DATE) == false) {
                        tmpValues.put(RelationColumns.MODIFIED_DATE, now);
                    }
                    result = db.update(RELATION_TABLE_NAME, tmpValues, selection,
                            selectionArgs);
                    getContext().getContentResolver().notifyChange(uri, null);
                    break;
                case RELATION_PATH_ID:
                    tmpValues = new ContentValues(values);
                    now = Long.valueOf(System.currentTimeMillis());
                    if (tmpValues.containsKey(RelationColumns.MODIFIED_DATE) == false) {
                        tmpValues.put(RelationColumns.MODIFIED_DATE, now);
                    }
                    result = db.update(
                            RELATION_TABLE_NAME,
                            tmpValues,
                            RelationColumns._ID
                                    + "="
                                    + uri.getPathSegments().get(1)
                                    + (!TextUtils.isEmpty(selection) ? " AND ("
                                            + selection + ')' : ""), selectionArgs);
                    getContext().getContentResolver().notifyChange(uri, null);
                    break;
            }
        } catch (Exception e) {
            result = -1;
        }
        return result;
    }

    public class MySettingCursor extends AbstractCursor {

        private String[] columnNames = null;

        private ArrayList<ArrayList<String>> allDatas = new ArrayList<ArrayList<String>>();
        private ArrayList<String> currentLineData = null;

        public MySettingCursor(String[] colNames) {
            this.columnNames = colNames;
        }

        public void addRow(String[] rowData) {
            if (rowData == null || rowData.length <= 0) {
                return;
            }
            ArrayList<String> tmpData = new ArrayList<String>();
            for (int i = 0; i < rowData.length; i++) {
                tmpData.add(rowData[i]);
            }
            allDatas.add(tmpData);
        }

        @Override
        public boolean onMove(int oldPosition, int newPosition) {
            if (newPosition < 0 || newPosition >= getCount()) {
                currentLineData = null;
                return false;
            }
            currentLineData = allDatas.get(newPosition);

            return super.onMove(oldPosition, newPosition);

        }

        @Override
        public String[] getColumnNames() {
            // TODO Auto-generated method stub
            return columnNames;
        }

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return allDatas.size();
        }

        @Override
        public double getDouble(int column) {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public float getFloat(int column) {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public int getInt(int column) {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public long getLong(int column) {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public short getShort(int column) {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public String getString(int column) {
            // TODO Auto-generated method stub
            if (currentLineData == null) {
                return null;
            }
            return currentLineData.get(column);
        }

        @Override
        public boolean isNull(int column) {
            // TODO Auto-generated method stub
            return currentLineData == null ? true : false;
        }

    }

    public static final class RelationColumns implements BaseColumns {
        public static final int WEIGHT_TYPE_COMMEN = 1;
        public static final int WEIGHT_TYPE_UNBIND = WEIGHT_TYPE_COMMEN + 1;
        public static final int WEIGHT_TYPE_WAIT_BIND = WEIGHT_TYPE_UNBIND + 1;
        public static final int WEIGHT_TYPE_BINDED = WEIGHT_TYPE_WAIT_BIND + 1;
        public static final Uri CONTENT_URI = Uri.parse("content://"
                + AUTHORITY + "/relations");
        /**
         * The MIME type of {@link #CONTENT_URI} providing a directory of notes.
         */
        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.FT.relations";

        /**
         * The MIME type of a {@link #CONTENT_URI} sub-directory of a single
         * note.
         */
        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.FT.relations";

        public static final String DEFAULT_SORT_ORDER = "modified DESC";
        /**
         * The name of relation member
         * <P>
         * Type: TEXT
         * </P>
         */
        public static final String NAME = "name";
        /**
         * The nickname of relation member
         * <P>
         * Type: TEXT
         * </P>
         */
        public static final String NICKNAME = "nickname";
        /**
         * The number of relation memebr
         * <p>
         * Type: TEXT
         * </p>
         */
        public static final String NUMBER = "number";
        /**
         * The IMEI of the relation member
         * <p>
         * Type: TEXT
         * </p>
         */
        public static final String IMEI = "imei";
        /*
         * the relationship with ME <p>Type: INTEGER</p>
         */
        public static final String RELATIONSHIP = "relationship";
        /*
         * the number weight type 1 普通，2，设置的关联号但未绑定，3,设置的关联号等待绑定4，设置的关联号已经绑定
         * <p>Type: INTEGER</p>
         */
        public static final String WEIGHT_TYPE = "weightType";
        /*
         * the number weight type 1 不在GPS队列，2，在GPS队列 <p>Type: INTEGER</p>
         */
        public static final String GPS_TYPE = "gpsType";
        /*
         * 1 GPS关闭，2，GPS打开 <p>Type: INTEGER</p>
         */
        public static final String GPS_ON = "gpsOn";
        /*
         * GPS经度 <p>Type: INTEGER</p>
         */
        public static final String GPS_LAT = "gpsLat";
        /*
         * GPS纬度 <p>Type: INTEGER</p>
         */
        public static final String GPS_LNG = "gpsLng";
        /**
         * The timestamp for when the note was last modified
         * <P>
         * Type: INTEGER (long from System.curentTimeMillis())
         * </P>
         */
        public static final String MODIFIED_DATE = "modified";
    }

}
